<script lang="ts" setup>
import { reactive, ref, watch, onMounted, computed } from "vue"
import * as PlanApi from "@/api/plan"
import { selectJiraByProjectId } from "@/api/jira"
import { fetchSelectList, fetchEnumSelectList } from "@/api/common"
import { type PlanData } from "@/api/plan/types/plan"
import { type SelectData } from "@/api/common/types/common"
import { type FormInstance, type FormRules, ElMessage, ElMessageBox } from "element-plus"
import { Search, Refresh, CirclePlus, Delete, Edit, RefreshRight } from "@element-plus/icons-vue"
import { usePagination } from "@/hooks/usePagination"
import { useTableSort } from "@/hooks/useTableSort"
import JiraReportDetail from "@/components/report/JiraReportDetail.vue"
import PlanInsert from "@/components/plan/PlanInsert.vue"
import { cloneDeep } from "lodash-es"
import dayjs from "dayjs"
import { useUserStore } from "@/store/modules/user"
import { checkPermission } from "@/utils/permission"
import { JiraData } from "@/api/jira/types/jira"

defineOptions({
  // 命名当前组件
  name: "Plan"
})

const userStore = useUserStore()
const userInfo = ref(userStore.userInfo)

const loading = ref<boolean>(false)
const { paginationData, handleCurrentChange, handleSizeChange } = usePagination()
// 排序
const { sortColumn, sortOrder, handleSortChange } = useTableSort({ statusText: "status" })

const today = (): string => {
  return dayjs().format("YYYY-MM-DD")
}
//#region 增
const DEFAULT_FORM_DATA: PlanData = {
  date: today(),
  projectId: 0,
  duration: 0,
  jira: "",
  note: "",
  status: ""
}
const formRef = ref<FormInstance | null>(null)
const formData = ref<PlanData>(cloneDeep(DEFAULT_FORM_DATA))

//所有的可选项目
const allProjectSelectOptions = ref<SelectData[]>([])
const fetchAllProjectSelectOptions = async () => {
  const data = await fetchSelectList("project")
  allProjectSelectOptions.value = data.data
}

// 计划状态
const planStatusOptions = ref<SelectData[]>()
const fetchPlanStatusOptions = async () => {
  const data = await fetchEnumSelectList("PlanStatus")
  planStatusOptions.value = data.data
}

// 项目下拉框
const projectSelectOptions = computed<SelectData[]>(() => {
  return allProjectSelectOptions.value
})

// 存放某个项目 的可选任务 jira列表
const projectJIraOptionsMap = reactive<Map<number, JiraData[]>>(new Map<number, JiraData[]>())
// 获取 项目下的任务jira 列表 和bugjira 列表
const fetchProjectJiraSelectOptions = async (projectId: number) => {
  const { data } = await selectJiraByProjectId(projectId)
  projectJIraOptionsMap.set(projectId, data)
}
// 当项目变化时处理， 清除其选择的jira列表
const handleProjectChange = (row: PlanData) => {
  debugger
  const selectedProject =
    mineProjectSelectOptions.value.find((project) => project.id === row.projectId) || row.projectId
  if (selectedProject) {
    // 不再手写  而是需要勾选
    // 当项目改变时且没有获取当前项目的jira列表时候，获取对应项目的jira列表
    if (row.projectId && !projectJIraOptionsMap.has(row.projectId)) {
      fetchProjectJiraSelectOptions(row.projectId)
    }
  }
}

//我的可选项目
const mineProjectSelectOptions = ref<SelectData[]>([])
// 小组下拉框
const groupSelectOptions = ref<SelectData[]>([])
const fetchGroupSelectOptions = async () => {
  const data = await fetchSelectList("group")
  groupSelectOptions.value = data.data
}
// 是否展示小组下拉框 ：admin 用户 或者term
const showGroup = computed<boolean>(() => {
  return checkPermission(["admin", "team"])
})

//用户下拉框
const userSelectOptions = ref<SelectData[]>([])
const fetchUserSelectOptions = async () => {
  const data = await fetchSelectList("user")
  userSelectOptions.value = data.data
}

// 根据 是否查询 项目日报列表 devManager 的变化和其他条件动态过滤 可选用户
const filteredUserSelectOptions = computed<SelectData[]>(() => {
  const { type, groupId } = userInfo.value || {}
  //选择的小组id
  const { groupId: selectedGroupId } = searchData
  // 1. 当选择了小组的时候 需要过滤小组；2.当为组长
  const needFilter: boolean = !!selectedGroupId || type === "team"
  if (needFilter) {
    const effectGroupId = selectedGroupId || groupId
    return userSelectOptions.value.filter((item) => item.pid === effectGroupId)
  }
  return userSelectOptions.value
})

const formRules: FormRules<PlanData> = reactive<FormRules>({})

const dialogVisible = ref<boolean>(false)
const handleUpdateReport = () => {
  formRef.value?.validate((valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)

    loading.value = true
    PlanApi.updatePlanApi(formData.value)
      .then(() => {
        ElMessage.success("操作成功")
        dialogVisible.value = false
        getTableData()
      })
      .finally(() => {
        loading.value = false
      })
  })
}
const resetForm = () => {
  formRef.value?.clearValidate()
  formData.value = cloneDeep(DEFAULT_FORM_DATA)
}
//#endregion

//#region 删
const handleDelete = (row: PlanData) => {
  if (row.id === undefined) return
  ElMessageBox.confirm("确认删除此计划吗?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(() => {
    if (row.id === undefined) return
    PlanApi.deletePlanApi(row.id).then(() => {
      ElMessage.success("删除成功")
      getTableData()
    })
  })
}
//#endregion

//#region 改
const handleUpdate = (row: PlanData) => {
  dialogVisible.value = true
  formData.value = cloneDeep(row)
  handleProjectChange(formData.value)
}

//#endregion

//#region 查
const tableData = ref<PlanData[]>([])
const searchFormRef = ref<FormInstance | null>(null)

const searchData = reactive({
  startDate: "",
  endDate: "",
  jira: "",
  status: "",
  note: "",
  userId: undefined as number | undefined, // 明确类型 ,
  projectId: undefined,
  groupId: undefined
})
//日期范围
const rangeDate = ref("")
const changeRangeDate = (val: Array<Date>) => {
  searchData.startDate = dayjs(val[0]).format("YYYY-MM-DD")
  searchData.endDate = dayjs(val[1]).format("YYYY-MM-DD")
}
const getTableData = () => {
  loading.value = true
  PlanApi.getPlanDataApi({
    page: paginationData.currentPage,
    size: paginationData.pageSize,
    sortColumn: sortColumn.value,
    sortOrder: sortOrder.value,
    ...searchData
  })
    .then(({ data }) => {
      paginationData.total = data.total
      tableData.value = data.datas
    })
    .catch(() => {
      tableData.value = []
    })
    .finally(() => {
      loading.value = false
    })
}
const handleSearch = () => {
  paginationData.currentPage === 1 ? getTableData() : (paginationData.currentPage = 1)
}
const resetSearch = () => {
  rangeDate.value = ""
  searchData.startDate = ""
  searchData.endDate = ""
  searchFormRef.value?.resetFields()
  handleSearch()
}
//#endregion

//#region 新增计划 抽屉 start *************************************

//通过子组件打开新增抽屉
const PlanInsertRef = ref<InstanceType<typeof PlanInsert> | null>(null)
const openInsertDrawer = () => {
  if (PlanInsertRef.value) {
    PlanInsertRef.value.openDrawer()
  }
}

//#endregion 新增计划 抽屉 end *************************************

// 某个jira 对应的工时详情
const jiraCode = ref("") // 存储传递给子组件的 Jira 号

// 切换抽屉显示状态并传入不同的 Jira Code
const handerShowReportDetail = (code: string) => {
  jiraCode.value = code // 设置传递给子组件的 code
}

const shortcuts = [
  {
    text: "上周",
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      return [start, end]
    }
  },
  {
    text: "上月",
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
      return [start, end]
    }
  },
  {
    text: "前三个月",
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
      return [start, end]
    }
  }
]

/** 监听分页参数的变化 */
watch(
  [() => paginationData.currentPage, () => paginationData.pageSize, () => sortColumn.value, () => sortOrder.value],
  getTableData,
  { immediate: false }
)

onMounted(() => {
  fetchGroupSelectOptions()
  fetchAllProjectSelectOptions()
  fetchUserSelectOptions()
  fetchPlanStatusOptions()
  searchData.userId = userInfo.value?.id ?? undefined
  // 先赋值当前用户 然后再查询表格
  getTableData()
})
</script>

<template>
  <div class="app-container">
    <el-card v-loading="loading" shadow="never" class="search-wrapper">
      <el-form ref="searchFormRef" :inline="true" :model="searchData" size="small">
        <el-form-item prop="" label="日期">
          <el-date-picker
            v-model="rangeDate"
            type="daterange"
            unlink-panels
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :shortcuts="shortcuts"
            @change="changeRangeDate"
          />
        </el-form-item>

        <el-form-item prop="projectId" label="所属项目">
          <el-select
            v-model="searchData.projectId"
            clearable
            filterable
            placeholder="请选择项目"
            style="width: 180px"
            :empty-values="[null]"
          >
            <el-option v-for="item in projectSelectOptions" :key="item.id" :label="item.text" :value="item.id">
              <span style="float: left">{{ item.text }}</span>
              <span style="float: right; color: var(--el-text-color-secondary); font-size: 13px">
                {{ item.additional }}
              </span>
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item prop="groupId" label="小组" v-if="showGroup">
          <el-select
            v-model="searchData.groupId"
            clearable
            placeholder="请选择小组"
            style="width: 180px"
            :empty-values="[null]"
          >
            <el-option v-for="item in groupSelectOptions" :key="item.id" :label="item.text" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item prop="userId" label="用户" v-if="showGroup">
          <el-select
            v-model="searchData.userId"
            clearable
            filterable
            placeholder="请选用户"
            style="width: 180px"
            :empty-values="[null]"
          >
            <el-option v-for="item in filteredUserSelectOptions" :key="item.id" :label="item.text" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item prop="status" label="状态">
          <el-select
            v-model="searchData.status"
            clearable
            filterable
            placeholder="请选择状态"
            style="width: 180px"
            :empty-values="[null]"
          >
            <el-option v-for="item in planStatusOptions" :key="item.id" :label="item.text" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item prop="jira" label="Jira号">
          <el-input v-model.trim="searchData.jira" placeholder="请输入" />
        </el-form-item>

        <el-form-item prop="note" label="备注">
          <el-input v-model.trim="searchData.note" placeholder="请输入" />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
          <el-button :icon="Refresh" @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card v-loading="loading" shadow="never">
      <div class="toolbar-wrapper">
        <div>
          <el-button type="primary" :icon="CirclePlus" @click="openInsertDrawer">新增计划</el-button>
        </div>
        <div>
          <!-- <el-tooltip content="下载">
            <el-button type="primary" :icon="Download" circle />
          </el-tooltip> -->
          <el-tooltip content="刷新当前页">
            <el-button type="primary" :icon="RefreshRight" circle @click="getTableData" />
          </el-tooltip>
        </div>
      </div>
      <div class="table-wrapper">
        <el-table :data="tableData" stripe :border="true" @sort-change="handleSortChange" size="small">
          <el-table-column prop="userName" label="姓名" align="center" width="120" sortable="custom" />
          <el-table-column prop="date" label="日期" align="center" width="120" sortable="custom" />
          <el-table-column prop="jira" label="Jira" align="center" width="150" sortable="custom">
            <template #default="scope">
              <el-tooltip class="box-item" effect="dark" content="查看jira工时详情" placement="top" :hide-after="0">
                <el-button type="primary" text size="small" @click="handerShowReportDetail(scope.row.jira)">{{
                  scope.row.jira
                }}</el-button>
              </el-tooltip>
            </template>
          </el-table-column>

          <el-table-column
            prop="projectName"
            label="项目"
            header-align="center"
            align="left"
            width="240"
            sortable="custom"
            show-overflow-tooltip
          />
          <el-table-column prop="duration" label="计划工时" align="center" width="120" sortable="custom" />
          <el-table-column prop="statusText" label="状态" align="center" width="120" sortable="custom" />
          <el-table-column prop="note" label="备注" header-align="center" align="left" show-overflow-tooltip />
          <el-table-column fixed="right" label="操作" width="120" align="center">
            <template #default="scope">
              <el-button type="primary" :icon="Edit" bg size="small" @click="handleUpdate(scope.row)" title="编辑" />
              <el-button type="danger" :icon="Delete" bg size="small" @click="handleDelete(scope.row)" title="删除" />
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="pager-wrapper">
        <el-pagination
          background
          :layout="paginationData.layout"
          :page-sizes="paginationData.pageSizes"
          :total="paginationData.total"
          :page-size="paginationData.pageSize"
          :currentPage="paginationData.currentPage"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>
    <!-- 新增/修改 -->

    <el-dialog v-model="dialogVisible" title="修改计划" @closed="resetForm" width="45%">
      <el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px" label-position="right">
        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item prop="projectId" label="所属项目">
              <el-select
                v-model="formData.projectId"
                clearable
                filterable
                placeholder="请选择项目"
                :empty-values="[null]"
                @change="handleProjectChange(formData)"
              >
                <el-option v-for="item in projectSelectOptions" :key="item.id" :label="item.text" :value="item.id" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item prop="date" label="日期">
              <el-date-picker
                v-model="formData.date"
                type="date"
                placeholder="选择一个日期"
                value-format="YYYY-MM-DD"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item prop="jira" label="jira号">
              <el-select
                v-model="formData.jira"
                clearable
                filterable
                placeholder="请选择Jira"
                :empty-values="[null]"
                size="small"
              >
                <el-option
                  v-show="projectJIraOptionsMap.has(formData.projectId)"
                  v-for="item in projectJIraOptionsMap.get(formData.projectId)"
                  :key="item.code"
                  :label="item.code"
                  :value="item.code"
                >
                  <template #default>
                    <el-tooltip :content="item.content" placement="top" :show-after="200">
                      <span>{{ item.code }}</span>
                    </el-tooltip>
                  </template>
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item prop="duration" label="计划工时">
              <el-input-number
                v-model="formData.duration"
                :min="0.5"
                :max="18"
                :step="0.5"
                step-strictly
                style="width: 90%"
                placeholder="单位:小时"
              >
                <template #suffix>
                  <span>小时</span>
                </template>
              </el-input-number>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item prop="status" label="计划状态">
              <el-select v-model="formData.status" clearable filterable placeholder="请选择状态">
                <el-option v-for="item in planStatusOptions" :key="item.id" :label="item.text" :value="item.id" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item prop="note" label="备注">
              <el-input v-model="formData.note" style="width: 100%" :rows="2" type="textarea" placeholder="备注" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleUpdateReport" :loading="loading">确认</el-button>
      </template>
    </el-dialog>

    <!-- #region 批量新增工时 抽屉 start-->
    <PlanInsert @operation-complete="getTableData" ref="PlanInsertRef" />
    <!-- #regionend 批量新增工时 抽屉 end-->

    <!-- jira 工时详情抽屉组件 -->
    <JiraReportDetail
      :code="jiraCode"
      @cleanCode="
        (newCode: string) => {
          jiraCode = newCode
        }
      "
    />
  </div>
</template>

<style lang="scss" scoped>
/* 使用深度选择器 >>> 或 /deep/ 或 ::v-deep */
:deep(.el-form-item__label) {
  font-weight: bold;
}

.search-wrapper {
  margin-bottom: 20px;

  :deep(.el-card__body) {
    padding-bottom: 2px;
  }
}

.toolbar-wrapper {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}

.table-wrapper {
  margin-bottom: 20px;
}

.pager-wrapper {
  display: flex;
  justify-content: flex-end;
}
</style>
